package com.bj58.data.emailreports.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import com.bj58.data.emailreports.dao.CommonDao;

public class CommonDataDeal {
	private CommonDao comDao = new CommonDao();
	private ReflectUtil reflectUtil = new ReflectUtil();
	
	/**根据VO,将每条SQL查询出来的指标,按照统一查询维度进行组装
	 * @param <T>
	 * @param sqlMap  
	 * 	key:SQL+DB标记(SQL结尾加以数据库标记，以:号隔开，如SQL:1)
	 * 		如下： 1：db_94_data_app： 94 data_app
	 *           2：db_131_data_bi： 131 data_app
	 *           3：hive_data_dw： hive data_dw
	 *           4：db_68_bi_sys： 68 bi_sys
	 *           5：db_131_ors： 131（3306）dbwww58com_online_revenue_stats
	 *       
	 *       后来DB:
	 * 	value:此SQL查询的指标名  
	 * 
	 * @param clazz   vo对象
	 * @param gbList 维度字段集合
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("static-access")
	public <T>List<T> AssembledDataBySqlMap(Map<String,List<String>> sqlMap,Class<T> clazz,List<String> gbList)throws Exception{
		
		//结果Map  根据gbList中的字段对应的值拼装作为KEY  各值以，号隔开
		TreeMap<String,T>  rsMap = new TreeMap<String,T>();
		
		/** 1.迭代所有的SQL，根据查询字段，查出对应的指标数据
		 *   2.迭代结果集 根据gbList存放的字段为KEY，查出是否已存在此KEY的对象数据
		 *   3.如无此KEY，则直接PUT   
		 *   4.此KEY已存在,则将此结果中的字段值，放入已存在对象中的对应字段
		 *   5.多个SQL查询同一个字段值,则将各SQL查出的值进行SUM
		 */
		for(Iterator<String> it = sqlMap.keySet().iterator(); it.hasNext();){
			String rSql = it.next();  //SQL+DB
			List<String> searchColList =sqlMap.get(rSql); //查询字段
			
			String searchSql = rSql.split(":")[0];
			int dbType  = Integer.parseInt(rSql.split(":")[1].trim());
			System.out.println(searchSql);
			List<T> rsList = comDao.getCommonStatList(searchSql, searchColList, clazz, dbType);
			
			for(T vo : rsList){
				String key = getKeyValue(gbList, vo, clazz);
				
				if(key.contains("旅游度假")){ 
					key = key.replace("旅游度假", "旅游酒店");
				}
				
				if(rsMap.containsKey(key)){
					T newVo = rsMap.get(key);
					for(String searchCol : searchColList){
						if(gbList.contains(searchCol)){
							continue;
						}
						Field  field =  clazz.getDeclaredField(searchCol);
						Method getMethod = reflectUtil.getGetterMethod(clazz, field);
						Method setMethod = reflectUtil.getSetterMethod(clazz, field);
						
						Class<?> filedCls = field.getType();
						Object columnValueObj = null;
						if(filedCls == int.class || filedCls == Integer.class) {
							int a = Integer.parseInt(getMethod.invoke(vo).toString())  ;
							int b = Integer.parseInt(getMethod.invoke(newVo).toString());
							columnValueObj = (Object)(a + b);
						}else if(filedCls == long.class || filedCls == Long.class){
							long a = Long.parseLong(getMethod.invoke(vo).toString())  ;
							long b = Long.parseLong(getMethod.invoke(newVo).toString());
							columnValueObj = (Object)(a + b);
						}else if(filedCls == double.class || filedCls == Double.class){
							double a = Double.parseDouble(getMethod.invoke(vo).toString());
							double b = Double.parseDouble(getMethod.invoke(newVo).toString());
							columnValueObj = (Object)(a + b);
						}else{
							columnValueObj = getMethod.invoke(vo);
						}
						
						setMethod.invoke(newVo, new Object[] { columnValueObj });
					}
				}else{
					rsMap.put(key, vo);
				}
			}
		}
		//最终数据集  
		List<T> rsList = new ArrayList<T>();
		for(Iterator<String> it = rsMap.keySet().iterator(); it.hasNext();){
			String key = it.next();
			rsList.add(rsMap.get(key));
		}
		return rsList;
	}
	
	
	/**将多组已查询出各自指标的对象集合，根据查询维度再次拼装
	 * @param <T>
	 * @param ObjectList
	 * @param clazz
	 * @param gbList
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("static-access")
	public <T>List<T> AssembledDataByObjectList(Map<String,List<T>> ObjectMap,Class<T> clazz,List<String> gbList)throws Exception{
		//结果Map  根据gbList中的字段对应的值拼装作为KEY  各值以，号隔开
		TreeMap<String,T>  rsMap = new TreeMap<String,T>();
		/** 
		 *   2.迭代结果集 根据gbList存放的字段为KEY，查出是否已存在此KEY的对象数据
		 *   3.如无此KEY，则直接PUT   
		 *   4.此KEY已存在,则将此结果中的字段值，放入已存在对象中的对应字段
		 */
		for(Iterator<String> it = ObjectMap.keySet().iterator(); it.hasNext();){
			String searchCols = it.next();
			List<T> rsList = ObjectMap.get(searchCols);
			
			for(T vo : rsList){
				String key = getKeyValue(gbList, vo, clazz);
				
				if(key.contains("旅游度假")){ //脑残的类别都不能保持一致....(╯‵□′)╯︵┻━┻
					key = key.replace("旅游度假", "旅游酒店");
				}
				
				if(rsMap.containsKey(key)){
					T newVo = rsMap.get(key);
					for(String searchCol : searchCols.split(",")){
						if(gbList.contains(searchCol)){
							continue;
						}
						Field  field =  clazz.getDeclaredField(searchCol);
						Method getMethod = reflectUtil.getGetterMethod(clazz, field);
						Method setMethod = reflectUtil.getSetterMethod(clazz, field);
						Object columnValueObj = getMethod.invoke(vo);
						setMethod.invoke(newVo, new Object[] { columnValueObj });
					}
				}else{
					rsMap.put(key, vo);
				}
			}
		}
		//最终数据集  
		List<T> rsList = new ArrayList<T>();
		for(Iterator<String> it = rsMap.keySet().iterator(); it.hasNext();){
			String key = it.next();
			rsList.add(rsMap.get(key));
		}
		return rsList;
	}
	
	
	/**获取组合KEY值
	 * @param <T>
	 * @param gbList
	 * @param vo
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("static-access")
	private <T>String getKeyValue (List<String> gbList,T vo,Class<?> clazz)throws Exception{
		StringBuffer key = new StringBuffer();
		
		for(int i = 0 ; i < gbList.size() ; i++){
			String gbValue = gbList.get(i);
			String value = "";
			if(null == reflectUtil.getGetterMethod(clazz, clazz.getDeclaredField(gbValue)).invoke(vo)){
				value ="";
			}else{
				 value = reflectUtil.getGetterMethod(clazz, clazz.getDeclaredField(gbValue)).invoke(vo).toString();
			}
			key.append(value+",");
		}
		
		return key.toString();
	}
	
	
	
}
